<template>
  <div class="advanced-animation-demo">
    <header class="demo-header">
      <h1>Vue 3 高级动画特性演示</h1>
      <p class="header-description">探索Vue 3中的高级动画技术，了解它们如何在实际业务场景中提升用户体验</p>
    </header>

    <!-- 动画场景切换 -->
    <div class="scene-tabs">
      <button
        v-for="scene in scenes"
        :key="scene.id"
        :class="['scene-tab', { active: activeScene === scene.id }]"
        @click="activeScene = scene.id"
      >
        {{ scene.name }}
      </button>
    </div>
    
    <!-- 1. 组合动画效果 - 产品详情展示场景 -->
    <div v-if="activeScene === 'combined'" class="demo-section">
      <h2>1. 组合动画效果</h2>
      <div class="scene-description">
        <p><strong>业务场景：</strong>产品详情页中的内容切换，如从产品概览到规格参数的过渡</p>
        <p>这种组合动画同时使用平移和缩放效果，为用户提供流畅的上下文切换体验。</p>
      </div>
      <div class="demo-controls">
        <button @click="toggleCombinedAnimation" class="btn-primary">
          {{ combinedVisible ? '显示产品规格' : '显示产品概览' }}
        </button>
      </div>
      <div class="demo-container">
        <transition name="combined" mode="out-in">
          <div v-if="combinedVisible" key="product-overview" class="combined-element product-overview">
            <h3>智能手机 Pro Max</h3>
            <div class="product-image">📱</div>
            <p>高性能处理器，超长续航，专业级相机系统</p>
            <span class="price">¥6999</span>
          </div>
          <div v-else key="product-specs" class="combined-element product-specs">
            <h3>产品规格</h3>
            <ul class="specs-list">
              <li>屏幕：6.7英寸 OLED</li>
              <li>存储：128GB / 256GB / 512GB</li>
              <li>相机：4800万像素主摄</li>
              <li>电池：5000mAh</li>
            </ul>
          </div>
        </transition>
      </div>
    </div>

    <!-- 2. 列表动画 - 购物车管理场景 -->
    <div v-if="activeScene === 'list'" class="demo-section">
      <h2>2. 列表动画</h2>
      <div class="scene-description">
        <p><strong>业务场景：</strong>购物车商品管理，添加、删除和重排商品时的动态反馈</p>
        <p>列表动画使购物体验更加流畅，用户可以清楚地看到商品的添加和移除过程。</p>
      </div>
      <div class="demo-controls">
        <button @click="addCartItem" class="btn-primary">添加商品</button>
        <button @click="removeRandomCartItem" class="btn-secondary">移除商品</button>
        <button @click="shuffleCartItems" class="btn-secondary">重新排序</button>
      </div>
      <div class="list-container cart-container">
        <transition-group name="list" tag="ul">
          <li v-for="(item, index) in cartItems" :key="item.id" class="list-item cart-item">
            <div class="item-content">
              <span class="item-icon">{{ item.icon }}</span>
              <div class="item-info">
                <div class="item-name">{{ item.name }}</div>
                <div class="item-price">¥{{ item.price ? item.price.toFixed(2) : '0.00' }}</div>
              </div>
              <span class="item-quantity">x{{ item.quantity }}</span>
            </div>
          </li>
        </transition-group>
        <div v-if="cartItems.length === 0" class="empty-cart">购物车为空</div>
      </div>
    </div>

    <!-- 3. 交错动画 - 图片库加载场景 -->
    <div v-if="activeScene === 'staggered'" class="demo-section">
      <h2>3. 交错动画</h2>
      <div class="scene-description">
        <p><strong>业务场景：</strong>图片库或产品展示墙的渐进式加载效果</p>
        <p>交错动画为每个元素添加不同的延迟，创造出有节奏的视觉体验，减轻一次性加载大量内容的视觉负担。</p>
      </div>
      <div class="demo-controls">
        <button @click="toggleStaggeredAnimation" class="btn-primary">
          {{ staggeredVisible ? '隐藏图片库' : '显示图片库' }}
        </button>
      </div>
      <div v-if="staggeredVisible" class="grid-container gallery-container">
        <transition-group name="staggered" tag="div" class="grid gallery-grid">
          <div
            v-for="(item, index) in galleryItems"
            :key="index"
            :style="{ animationDelay: index * 50 + 'ms' }"
            class="grid-item gallery-item"
          >
            {{ item.icon }}
          </div>
        </transition-group>
      </div>
    </div>

    <!-- 4. 动态过渡 - 用户通知场景 -->
    <div v-if="activeScene === 'dynamic'" class="demo-section">
      <h2>4. 动态过渡</h2>
      <div class="scene-description">
        <p><strong>业务场景：</strong>根据通知类型（成功、警告、错误）使用不同的过渡效果</p>
        <p>动态过渡允许根据内容类型或业务逻辑选择最合适的动画效果，增强信息传递的有效性。</p>
      </div>
      <div class="demo-controls">
        <select v-model="notificationType" class="form-control">
          <option value="success">成功通知</option>
          <option value="warning">警告通知</option>
          <option value="error">错误通知</option>
        </select>
        <button @click="toggleNotification" class="btn-primary">
          {{ notificationVisible ? '隐藏通知' : '显示通知' }}
        </button>
      </div>
      <div class="demo-container notification-container">
        <transition :name="notificationTransition" mode="out-in">
          <div v-if="notificationVisible" :key="notificationType" class="notification" :class="notificationType">
            <span class="notification-icon">{{ notificationIcon }}</span>
            <div class="notification-content">
              <div class="notification-title">{{ notificationTitle }}</div>
              <div class="notification-message">{{ notificationMessage }}</div>
            </div>
          </div>
        </transition>
      </div>
    </div>

    <!-- 5. JavaScript动画钩子 - 数据可视化场景 -->
    <div v-if="activeScene === 'js'" class="demo-section">
      <h2>5. JavaScript动画钩子</h2>
      <div class="scene-description">
        <p><strong>业务场景：</strong>数据仪表盘加载动画，展示数据从无到有的过程</p>
        <p>JavaScript动画钩子提供了对动画过程的精确控制，适用于复杂的数据可视化和需要精确计时的交互。</p>
      </div>
      <div class="demo-controls">
        <button @click="toggleChartAnimation" class="btn-primary">
          {{ chartAnimationActive ? '重置图表' : '加载图表' }}
        </button>
      </div>
      <div class="demo-container chart-container">
        <transition
          @before-enter="beforeChartEnter"
          @enter="chartEnter"
          @leave="chartLeave"
          :css="false"
        >
          <div v-if="chartAnimationActive" class="chart" ref="chartElement">
            <div class="chart-title">月度销售数据</div>
            <div class="chart-bars">
              <div v-for="(bar, index) in chartBars" :key="index" class="chart-bar">
                <div class="bar-fill" :style="{ height: bar.height + '%' }"></div>
                <div class="bar-label">{{ bar.label }}</div>
              </div>
            </div>
          </div>
        </transition>
      </div>
    </div>

    <!-- 6. 性能优化的动画 - 粒子效果场景 -->
    <div v-if="activeScene === 'optimized'" class="demo-section">
      <h2>6. 性能优化的动画</h2>
      <div class="scene-description">
        <p><strong>业务场景：</strong>庆祝活动特效、背景装饰或交互反馈粒子效果</p>
        <p>通过使用transform属性、will-change和requestAnimationFrame，可以创建高性能的复杂动画效果，即使在低端设备上也能保持流畅。</p>
      </div>
      <div class="demo-controls">
        <div class="control-group">
          <label for="particleCount">粒子数量:</label>
          <input 
            id="particleCount" 
            type="range" 
            v-model.number="particleCount" 
            min="10" 
            max="100" 
            step="10"
            class="range-control"
          >
          <span>{{ particleCount }}</span>
        </div>
        <button @click="toggleParticles" class="btn-primary">
          {{ particlesActive ? '停止粒子' : '开始粒子' }}
        </button>
      </div>
      <div class="demo-container particle-container">
        <div v-if="particlesActive" class="particles-wrapper">
          <div
            v-for="i in particleCount"
            :key="i"
            class="particle"
            :style="particleStyles(i)"
          >
            {{ getParticleIcon() }}
          </div>
        </div>
      </div>
    </div>

    <!-- 底部代码和最佳实践部分 -->
    <div class="code-section">
      <h2>动画原理与最佳实践</h2>
      <div class="best-practices-wrapper">
        <div class="practice-item">
          <h3>性能优化要点</h3>
          <ul class="best-practices-list">
            <li>使用 <code>transform</code> 和 <code>opacity</code> 属性进行动画，避免重排(reflow)</li>
            <li>使用 <code>will-change</code> 属性通知浏览器元素将要变化</li>
            <li>对于复杂动画，考虑使用 <code>requestAnimationFrame</code></li>
            <li>使用 <code>v-memo</code> 避免不必要的组件重新渲染</li>
            <li>对于大量元素的动画，考虑使用 CSS Grid 或 Flexbox</li>
          </ul>
        </div>
        
        <div class="practice-item">
          <h3>代码示例</h3>
          <CodeBlock :code="animationBestPractices" language="javascript" title="动画最佳实践" />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onUnmounted, nextTick } from 'vue'
import CodeBlock from '@components/CodeBlock.vue'

// 场景切换
const activeScene = ref('combined')
const scenes = ref([
  { id: 'combined', name: '组合动画' },
  { id: 'list', name: '列表动画' },
  { id: 'staggered', name: '交错动画' },
  { id: 'dynamic', name: '动态过渡' },
  { id: 'js', name: 'JS动画钩子' },
  { id: 'optimized', name: '性能优化动画' }
])

// 1. 组合动画 - 产品详情展示场景
const combinedVisible = ref(true)

// 2. 列表动画 - 购物车管理场景
const cartItems = ref([
  { id: 1, name: '无线耳机', price: 799, quantity: 1, icon: '🎧' },
  { id: 2, name: '智能手表', price: 1599, quantity: 1, icon: '⌚' },
  { id: 3, name: '移动电源', price: 199, quantity: 2, icon: '🔋' }
])
let cartItemId = 4
const productCatalog = [
  { name: '平板电脑', price: 3299, icon: '📱' },
  { name: '蓝牙音箱', price: 399, icon: '🔊' },
  { name: '游戏手柄', price: 299, icon: '🎮' },
  { name: '相机', price: 5999, icon: '📷' },
  { name: '键盘', price: 499, icon: '⌨️' },
  { name: '鼠标', price: 199, icon: '🖱️' }
]

// 3. 交错动画 - 图片库加载场景
const staggeredVisible = ref(false)
const galleryItems = ref(Array.from({ length: 16 }, (_, i) => ({
  id: i,
  icon: ['🏞️', '🌄', '🌅', '🌉', '🏙️', '🏠', '🏯', '🗼'][i % 8]
})))

// 4. 动态过渡 - 用户通知场景
const notificationVisible = ref(false)
const notificationType = ref('success')
const notificationTitle = computed(() => {
  const titles = {
    success: '操作成功',
    warning: '注意',
    error: '错误'
  }
  return titles[notificationType.value]
})
const notificationMessage = computed(() => {
  const messages = {
    success: '您的请求已成功处理',
    warning: '请检查您的输入信息',
    error: '处理请求时发生错误'
  }
  return messages[notificationType.value]
})
const notificationIcon = computed(() => {
  const icons = {
    success: '✅',
    warning: '⚠️',
    error: '❌'
  }
  return icons[notificationType.value]
})
const notificationTransition = computed(() => {
  const transitions = {
    success: 'success',
    warning: 'warning',
    error: 'error'
  }
  return transitions[notificationType.value]
})

// 5. JavaScript动画钩子 - 数据可视化场景
const chartAnimationActive = ref(false)
const chartElement = ref(null)
const chartBars = ref([
  { label: '1月', height: 30 },
  { label: '2月', height: 50 },
  { label: '3月', height: 40 },
  { label: '4月', height: 70 },
  { label: '5月', height: 60 },
  { label: '6月', height: 85 }
])
let chartAnimationFrame = null

// 6. 性能优化的动画 - 粒子效果场景
const particlesActive = ref(false)
const particleCount = ref(30)
let particlesAnimationFrame = null

// 动画最佳实践代码
const animationBestPractices = `
// 1. 组合CSS类实现复杂动画
.combined-enter-active,
.combined-leave-active {
  transition: all 0.5s ease;
}
.combined-enter-from {
  opacity: 0;
  transform: scale(0.8) translateX(-30px);
}
.combined-leave-to {
  opacity: 0;
  transform: scale(0.8) translateX(30px);
}

// 2. 使用will-change优化性能
.animated-element {
  will-change: transform, opacity;
}

// 3. JavaScript钩子动画示例
const beforeEnter = (el) => {
  el.style.opacity = 0
  el.style.transform = 'scale(0)'
}

const enter = (el, done) => {
  // 使用GSAP或其他库进行复杂动画
  // 完成后调用done()
}

// 4. 使用v-memo避免不必要的重渲染
<div v-for="item in items" :key="item.id" v-memo="[item.id, item.visible]">
  {{ item.text }}
</div>
`

// 1. 组合动画 - 产品详情切换
const toggleCombinedAnimation = () => {
  combinedVisible.value = !combinedVisible.value
}

// 2. 购物车相关功能
const addCartItem = () => {
  const randomProduct = productCatalog[Math.floor(Math.random() * productCatalog.length)]
  cartItems.value.push({
    id: cartItemId++,
    ...randomProduct,
    quantity: Math.floor(Math.random() * 3) + 1
  })
}

const removeRandomCartItem = () => {
  if (cartItems.value.length > 0) {
    const index = Math.floor(Math.random() * cartItems.value.length)
    cartItems.value.splice(index, 1)
  }
}

const shuffleCartItems = () => {
  const newItems = [...cartItems.value]
  for (let i = newItems.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1))
    ;[newItems[i], newItems[j]] = [newItems[j], newItems[i]]
  }
  cartItems.value = newItems
}

// 3. 交错动画 - 图片库
const toggleStaggeredAnimation = () => {
  staggeredVisible.value = !staggeredVisible.value
}

// 4. 动态通知
const toggleNotification = () => {
  notificationVisible.value = !notificationVisible.value
}

// 5. 图表动画钩子
const beforeChartEnter = (el) => {
  el.style.opacity = 0
  // 重置所有条形图高度
  const bars = el.querySelectorAll('.bar-fill')
  bars.forEach(bar => {
    bar.style.height = '0%'
  })
}

const chartEnter = (el, done) => {
  let start = null
  const bars = el.querySelectorAll('.bar-fill')
  const targetHeights = chartBars.value.map(bar => bar.height)
  
  const animate = (timestamp) => {
    if (!start) start = timestamp
    const progress = timestamp - start
    const duration = 1000 // 动画持续时间
    
    if (progress < duration) {
      const easeProgress = easeOutQuad(progress / duration)
      el.style.opacity = easeProgress
      
      // 为每个条形图应用动画
      bars.forEach((bar, index) => {
        bar.style.height = (targetHeights[index] * easeProgress) + '%'
      })
      
      chartAnimationFrame = requestAnimationFrame(animate)
    } else {
      el.style.opacity = 1
      bars.forEach((bar, index) => {
        bar.style.height = targetHeights[index] + '%'
      })
      done()
    }
  }
  
  chartAnimationFrame = requestAnimationFrame(animate)
}

const chartLeave = (el, done) => {
  let start = null
  const bars = el.querySelectorAll('.bar-fill')
  
  const animate = (timestamp) => {
    if (!start) start = timestamp
    const progress = timestamp - start
    const duration = 500
    
    if (progress < duration) {
      const easeProgress = 1 - easeOutQuad(progress / duration)
      el.style.opacity = easeProgress
      
      bars.forEach(bar => {
        bar.style.height = (parseInt(bar.style.height) * easeProgress) + '%'
      })
      
      chartAnimationFrame = requestAnimationFrame(animate)
    } else {
      el.style.opacity = 0
      bars.forEach(bar => {
        bar.style.height = '0%'
      })
      done()
    }
  }
  
  chartAnimationFrame = requestAnimationFrame(animate)
}

const toggleChartAnimation = () => {
  chartAnimationActive.value = !chartAnimationActive.value
}

// 6. 粒子效果
const toggleParticles = () => {
  particlesActive.value = !particlesActive.value
  
  if (particlesActive.value) {
    animateParticles()
  } else if (particlesAnimationFrame) {
    cancelAnimationFrame(particlesAnimationFrame)
  }
}

const particleIcons = ['⭐', '✨', '🌟', '💫']

const getParticleIcon = () => {
  return particleIcons[Math.floor(Math.random() * particleIcons.length)]
}

const particleStyles = (index) => {
  const time = Date.now() / 1000
  const speed = 0.1 + (index % 5) * 0.05
  const x = Math.sin(time * speed + index) * 30
  const y = Math.cos(time * speed + index) * 30
  const rotate = Math.sin(time * speed) * 180
  
  return {
    transform: `translate(${x}px, ${y}px) rotate(${rotate}deg)`,
    transition: 'transform 0.1s linear'
  }
}

const animateParticles = () => {
  if (!particlesActive.value) return
  
  // 粒子动画会通过CSS transform直接在模板中更新，这里只是保持动画循环
  particlesAnimationFrame = requestAnimationFrame(animateParticles)
}

// 缓动函数
const easeOutQuad = (t) => t * (2 - t)

// 生命周期钩子
onMounted(() => {
  // 组件挂载后的初始化
})

// 清理
onUnmounted(() => {
  if (chartAnimationFrame) {
    cancelAnimationFrame(chartAnimationFrame)
  }
  if (particlesAnimationFrame) {
    cancelAnimationFrame(particlesAnimationFrame)
  }
})
</script>

<style scoped>
.advanced-animation-demo {
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

/* 头部样式 */
.demo-header {
  text-align: center;
  margin-bottom: 40px;
  padding: 20px 0;
  border-bottom: 2px solid #eaeaea;
}

.demo-header h1 {
  color: #333;
  font-size: 2.2rem;
  margin-bottom: 10px;
}

.header-description {
  color: #666;
  font-size: 1.1rem;
  max-width: 800px;
  margin: 0 auto;
}

/* 场景标签切换 */
.scene-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  margin-bottom: 40px;
  background-color: #f8f9fa;
  padding: 10px;
  border-radius: 8px;
}

.scene-tab {
  padding: 12px 20px;
  border: 1px solid #ddd;
  background-color: white;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-weight: 500;
}

.scene-tab:hover {
  background-color: #f0f0f0;
  border-color: #42b883;
}

.scene-tab.active {
  background-color: #42b883;
  color: white;
  border-color: #42b883;
}

/* 通用演示区块样式 */
.demo-section {
  margin-bottom: 60px;
  padding: 30px;
  background-color: white;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  border: 1px solid #eaeaea;
}

.demo-section h2 {
  margin-top: 0;
  margin-bottom: 15px;
  color: #42b883;
  font-size: 1.8rem;
  border-bottom: 2px solid #42b883;
  padding-bottom: 10px;
}

/* 场景描述 */
.scene-description {
  background-color: #f8f9fa;
  padding: 15px;
  border-radius: 8px;
  margin-bottom: 25px;
  border-left: 4px solid #42b883;
}

.scene-description p {
  margin: 8px 0;
  color: #555;
  line-height: 1.6;
}

.scene-description strong {
  color: #42b883;
  font-weight: 600;
}

/* 控制区域样式 */
.demo-controls {
  margin-bottom: 25px;
  display: flex;
  gap: 15px;
  flex-wrap: wrap;
  align-items: center;
}

.control-group {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.control-group label {
  font-weight: 500;
  color: #555;
  white-space: nowrap;
}

.range-control {
  width: 150px;
}

.btn-primary {
  background-color: #42b883;
  color: white;
  border: none;
  padding: 12px 24px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 1rem;
  font-weight: 500;
  transition: all 0.3s ease;
  box-shadow: 0 2px 4px rgba(66, 184, 131, 0.3);
}

.btn-primary:hover {
  background-color: #369974;
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(66, 184, 131, 0.4);
}

.btn-secondary {
  background-color: #6c757d;
  color: white;
  border: none;
  padding: 12px 24px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 1rem;
  font-weight: 500;
  transition: all 0.3s ease;
}

.btn-secondary:hover {
  background-color: #5a6268;
  transform: translateY(-1px);
}

.form-control {
  padding: 12px;
  border: 1px solid #ddd;
  border-radius: 6px;
  font-size: 1rem;
  flex: 1;
  min-width: 150px;
  transition: border-color 0.3s ease;
}

.form-control:focus {
  outline: none;
  border-color: #42b883;
  box-shadow: 0 0 0 2px rgba(66, 184, 131, 0.2);
}

/* 通用容器样式 */
.demo-container {
  height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #fafafa;
  border-radius: 8px;
  overflow: hidden;
  position: relative;
  border: 1px solid #eaeaea;
  padding: 20px;
}

/* 1. 产品展示场景样式 */
.product-overview,
.product-specs {
  text-align: center;
  width: 100%;
  max-width: 400px;
  padding: 30px;
  background: linear-gradient(135deg, #42b883 0%, #35495e 100%);
  color: white;
  border-radius: 12px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
}

.product-overview h3,
.product-specs h3 {
  margin-top: 0;
  margin-bottom: 20px;
  font-size: 1.5rem;
  color: white;
}

.product-image {
  font-size: 4rem;
  margin: 20px 0;
}

.product-overview p {
  margin-bottom: 20px;
  opacity: 0.9;
}

.price {
  display: inline-block;
  font-size: 1.8rem;
  font-weight: bold;
  background-color: rgba(255, 255, 255, 0.2);
  padding: 8px 16px;
  border-radius: 6px;
}

.specs-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.specs-list li {
  padding: 10px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}

.specs-list li:last-child {
  border-bottom: none;
}

/* 2. 购物车场景样式 */
.cart-container {
  background-color: #fafafa;
  border-radius: 8px;
  padding: 20px;
  min-height: 300px;
}

.cart-item {
  padding: 15px;
  margin-bottom: 12px;
  background-color: white;
  border-radius: 8px;
  transition: all 0.3s ease;
  border: 1px solid #eaeaea;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.cart-item:hover {
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

.item-content {
  display: flex;
  align-items: center;
  gap: 15px;
}

.item-icon {
  font-size: 2rem;
}

.item-info {
  flex: 1;
}

.item-name {
  font-weight: 500;
  color: #333;
}

.item-price {
  color: #42b883;
  font-weight: 600;
}

.item-quantity {
  background-color: #f0f0f0;
  padding: 4px 10px;
  border-radius: 4px;
  font-weight: 500;
}

.empty-cart {
  text-align: center;
  padding: 40px;
  color: #999;
  font-style: italic;
}

/* 3. 图片库场景样式 */
.gallery-container {
  background-color: #fafafa;
  border-radius: 8px;
  padding: 20px;
  overflow: hidden;
}

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 15px;
}

.gallery-item {
  aspect-ratio: 1;
  background-color: white;
  color: #42b883;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  font-size: 3rem;
  font-weight: bold;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  animation: staggeredFadeIn 0.5s ease-out both;
  transition: transform 0.3s ease;
}

.gallery-item:hover {
  transform: scale(1.05) rotate(5deg);
}

/* 4. 通知场景样式 */
.notification-container {
  height: auto;
  min-height: 150px;
  align-items: flex-start;
  padding: 20px;
}

.notification {
  width: 100%;
  max-width: 500px;
  padding: 20px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 15px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.notification.success {
  background-color: #d4edda;
  border-left: 4px solid #28a745;
  color: #155724;
}

.notification.warning {
  background-color: #fff3cd;
  border-left: 4px solid #ffc107;
  color: #856404;
}

.notification.error {
  background-color: #f8d7da;
  border-left: 4px solid #dc3545;
  color: #721c24;
}

.notification-icon {
  font-size: 2rem;
}

.notification-content {
  flex: 1;
}

.notification-title {
  font-weight: 600;
  margin-bottom: 5px;
}

/* 通知过渡动画 */
.success-enter-active,
.success-leave-active {
  transition: all 0.5s ease;
}

.success-enter-from {
  opacity: 0;
  transform: translateX(-30px);
}

.success-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

.warning-enter-active,
.warning-leave-active {
  transition: all 0.5s ease;
}

.warning-enter-from {
  opacity: 0;
  transform: scale(0.8);
}

.warning-leave-to {
  opacity: 0;
  transform: scale(0.8);
}

.error-enter-active,
.error-leave-active {
  transition: all 0.5s ease;
}

.error-enter-from {
  opacity: 0;
  transform: translateY(-20px);
}

.error-leave-to {
  opacity: 0;
  transform: translateY(20px);
}

/* 5. 图表场景样式 */
.chart-container {
  height: 400px;
  align-items: flex-end;
}

.chart {
  width: 100%;
  height: 100%;
  padding: 20px;
}

.chart-title {
  text-align: center;
  font-weight: 600;
  margin-bottom: 20px;
  color: #333;
}

.chart-bars {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  height: calc(100% - 40px);
  gap: 10px;
  padding-bottom: 20px;
}

.chart-bar {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
}

.bar-fill {
  width: 100%;
  background: linear-gradient(to top, #42b883, #35495e);
  border-radius: 4px 4px 0 0;
  min-height: 10px;
  transition: height 0.5s ease;
}

.bar-label {
  margin-top: 10px;
  font-weight: 500;
  color: #666;
}

/* 6. 粒子效果场景样式 */
.particle-container {
  height: 400px;
  position: relative;
  overflow: hidden;
  background: radial-gradient(circle, #f0f9ff 0%, #e0f2fe 100%);
}

.particles-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  will-change: transform;
}

.particle {
  position: absolute;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  left: calc(50% - 20px);
  top: calc(50% - 20px);
  will-change: transform;
  animation: float 3s ease-in-out infinite;
}

@keyframes float {
  0%, 100% {
    transform: translate(0, 0) rotate(0deg);
  }
  50% {
    transform: translate(0, -10px) rotate(5deg);
  }
}

/* 底部最佳实践样式 */
.code-section {
  margin-top: 60px;
  padding: 30px;
  background-color: white;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  border: 1px solid #eaeaea;
}

.code-section h2 {
  margin-top: 0;
  margin-bottom: 30px;
  color: #35495e;
  text-align: center;
  border-bottom: none;
}

.best-practices-wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 30px;
}

.practice-item h3 {
  margin-top: 0;
  margin-bottom: 15px;
  color: #42b883;
  font-size: 1.3rem;
}

.best-practices-list {
  padding-left: 20px;
  line-height: 1.8;
}

.best-practices-list li {
  margin-bottom: 12px;
  color: #555;
}

.best-practices-list code {
  background-color: #f0f0f0;
  padding: 2px 6px;
  border-radius: 3px;
  font-family: 'Courier New', Courier, monospace;
  font-size: 0.9em;
  color: #e74c3c;
}

/* 响应式设计 */
@media (max-width: 992px) {
  .best-practices-wrapper {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .demo-header h1 {
    font-size: 1.8rem;
  }
  
  .scene-tabs {
    flex-direction: column;
  }
  
  .scene-tab {
    width: 100%;
  }
  
  .demo-controls {
    flex-direction: column;
    align-items: stretch;
  }
  
  .btn-primary,
  .btn-secondary {
    width: 100%;
  }
  
  .gallery-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  
  .chart-bars {
    flex-wrap: wrap;
  }
  
  .chart-bar {
    min-width: 40px;
  }
  
  .control-group {
    justify-content: space-between;
  }
  
  .range-control {
    width: 100%;
  }
}

@media (max-width: 480px) {
  .advanced-animation-demo {
    padding: 10px;
  }
  
  .demo-section {
    padding: 15px;
  }
  
  .gallery-grid {
    grid-template-columns: 1fr;
  }
  
  .notification {
    flex-direction: column;
    text-align: center;
  }
  
  .item-content {
    flex-direction: column;
    text-align: center;
  }
}
</style>